from rest_framework import serializers
from goods.models import SKU
from .models import OrderInfo,OrderGoods
from decimal import Decimal
from django.utils import timezone
from django_redis import get_redis_connection
from django.db import transaction


class CartSKUSerializer(serializers.ModelSerializer):
    """订单中商品"""
    count =serializers.IntegerField(label='商品购买数量')
    class Meta:
        model =SKU
        fields =['id', 'name', 'default_image_url', 'price', 'count']
class OrderSettlementSerializer(serializers.Serializer):
    """去结算"""
    freight = serializers.DecimalField(label='运费', max_digits=10, decimal_places=2)
    skus =CartSKUSerializer(many=True)

class CommitOrderSerializer(serializers.ModelSerializer):
    """保存订单"""
    class Meta:
        model =OrderInfo
        fields =['order_id','address','pay_method']
        read_only_fields =['order_id']
        extra_kwargs = {
            'address': {
                'write_only': True,

            },
            'pay_method': {
                'write_only': True,

            }
        }
    def create(self,validated_data):
        """重写此方法做四张表的操作"""
        user =self.context['request'].user
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' %user.id)
        address =validated_data.get('address')
        pay_method =validated_data.get('pay_method')
        status =(OrderInfo.ORDER_STATUS_ENUM['UNPAID']
        if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY']
                 else OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
        # 手动开启事务
        with transaction.atomic():
        # 创建一个保存点
            save_point =transaction.savepoint()
            try:
                # 创建订单信息
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal('0.00'),
                    freight=Decimal('10.00'),
                    pay_method=pay_method,
                    status=status
                )
                redis_conn =get_redis_connection('cart')
                cart_dict_redis =redis_conn.hgetall('cart_%s'%user.id)
                selected_ids =redis_conn.smembers('selected_%s'%user.id)
                cart_dict ={}
                for sku_id_bytes in selected_ids:
                    cart_dict[int(sku_id_bytes)] =int(cart_dict_redis[sku_id_bytes])


                for sku_id in cart_dict:
                    while True:
                        sku =SKU.objects.get(id =sku_id)
                        buy_count =cart_dict[sku_id]

                        origin_stock =sku.stock
                        origin_sales =sku.sales
                        import time
                        time.sleep(5)

                        if origin_stock <buy_count:
                            raise serializers.ValidationError('库存不足')

                        new_stock =origin_stock -buy_count
                        new_sales =origin_sales +buy_count

                        # sku.stock =new_stock
                        # sku.sales =new_sales
                        # sku.save()
                        result = SKU.objects.filter(stock=origin_stock, sales=origin_sales, id=sku_id).update(
                            stock=new_stock, sales=new_sales)

                        if result ==0:
                            continue

                        spu =sku.goods
                        spu.sales +=buy_count
                        spu.save()

                        oderGood = OrderGoods.objects.create(
                            order =order,
                            sku =sku,
                            count =buy_count,
                            price =sku.price

                        )
                        order.total_count +=buy_count
                        order.total_amount += (sku.price * buy_count)

                        break

                order.total_amount += order.freight
                order.save()
            except Exception:
                transaction.savepoint_rollback(save_point)

                raise serializers.ValidationError('库存不足')
            else:
                transaction.savepoint_commit(save_point)
        return order